package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"go-grpc/grpc-gateway/service"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/grpclog"
	"io/ioutil"
	"log"
	"net/http"
)

const (
	// ServerAddress gRPC服务地址
	ServerAddress = "127.0.0.1:8888"

	//ClientAddress 是浏览器等发送http请求时的地址
	ClientAddress = "127.0.0.1:8080"
)

func main() {
	ctx := context.Background()
	ctx, cancelFunc := context.WithCancel(ctx)
	defer cancelFunc()

	//1、创建路由
	mux := runtime.NewServeMux()

	//2、加入认证证书
	opt := []grpc.DialOption{grpc.WithTransportCredentials(GetClientCreds())}

	//3、注册请求服务端的方法
	err := service.RegisterGrpcGateWayServiceHandlerFromEndpoint(ctx, mux, ServerAddress, opt)
	if err != nil {
		log.Fatalf("cannot start grpc gateway: %v", err)
	}

	//4、启动并监听http请求
	err = http.ListenAndServe(ClientAddress, mux)
	if err != nil {
		log.Fatalf("cannot listen and server: %v", err)
	}
	log.Println("ClientServer listen on " + ServerAddress + " with TLS")

}

//加入客户端认证证书
func GetClientCreds() credentials.TransportCredentials {
	// TLS连接
	//从证书相关文件中读取和解析信息，得到证书公钥、密钥对
	cert, err := tls.LoadX509KeyPair("grpc-gateway/keys2/client.pem", "grpc-gateway/keys2/client.key")
	if err != nil {
		grpclog.Fatalf("Failed to find client credentials %v", err)
	}

	certPool := x509.NewCertPool()
	ca, err := ioutil.ReadFile("grpc-gateway/keys2/ca.pem")
	if err != nil {
		grpclog.Fatalf("Failed to find root credentials %v", err)
	}

	certPool.AppendCertsFromPEM(ca)

	creds := credentials.NewTLS(&tls.Config{
		Certificates: []tls.Certificate{cert}, //客户端证书
		ServerName:   "ximu.info",             //注意这里的参数为配置文件中所允许的ServerName，也就是其中配置的DNS...
		RootCAs:      certPool,
	})
	return creds
}
